/*
 * Copyright (C) 2012-2013 Michael L.R. Marques
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 * 
 * Contact: michaellrmarques@gmail.com
 */

package com.jm.jmsql.utils;

import com.jm.commons.logging.LogSystem;
import com.jm.commons.settings.SettingsException;
import java.awt.Frame;
import java.awt.Rectangle;
import java.io.File;
import javax.swing.UIManager.LookAndFeelInfo;

/**
 *
 * @created Nov 21, 2012
 * @author Michael L.R. Marques
 */
public class Settings extends com.jm.commons.settings.Settings {
    
    /**
     * 
     * @return 
     */
    public static Class getClazz() {
        return (new Settings()).getClass();
    }
    
    /**
     * 
     * @return 
     */
    public static void initializeSettings() {
        // Check if settings file exists
        if (!Settings.getSettingsFile().exists()) {
            // Set default application bounds
            Settings.setApplicationBounds(Constants.DEFAULT_BOUNDS);
            Settings.setApplicationBoundsDefault(Constants.DEFAULT_BOUNDS);
            // Set default db libs
            Settings.setDatabaseLibrarysDirectory("./dblibs");
            Settings.setDatabaseLibrarysDirectoryDefault("./dblibs");
            // Set default databases
            Settings.setDatabasesFile("./settings/databases.xml");
            Settings.setDatabasesFileDefault("./settings/databases.xml");
            // Set default dbxplora width
            Settings.setDBXPloraWidth(200);
            Settings.setDBXPloraWidthDefault(200);
            // Set default startup page
            Settings.showStartupPage(true);
            // Set default logging
            Settings.setLogging(false);
            // Set default look and feel
            Settings.setLookAndFeel(javax.swing.UIManager.getSystemLookAndFeelClassName());
            Settings.setLookAndFeelDefault(javax.swing.UIManager.getSystemLookAndFeelClassName());
            // Set defaul SQL Location
            Settings.setSQLLocation(new File(System.getProperty("./")));
            Settings.setSQLLocationDefault(new File(System.getProperty("./")));
            try {
                // Save settings changes
                Settings.save();
            } catch (SettingsException se) {
                LogSystem.log(getClazz(), getClazz().getEnclosingMethod(), "Saving Settings", se);
            }
        }
        // Set the bounds
        if (Settings.getApplicationBounds() == null) {
            Settings.setApplicationBounds(Constants.DEFAULT_BOUNDS);
            Settings.setApplicationBoundsDefault(Constants.DEFAULT_BOUNDS);
            try {
                Settings.save();
            } catch (SettingsException se) {
                LogSystem.log(getClazz(), getClazz().getEnclosingMethod(), "Saving Settings", se);
            }
        }
        // Set the database librarys directory
        if (Settings.getDatabaseLibrarysDirectory() == null ||
                Settings.getDatabaseLibrarysDirectory().exists()) {
            Settings.setDatabaseLibrarysDirectory("./dblibs");
            Settings.setDatabaseLibrarysDirectoryDefault("./dblibs");
            try {
                Settings.save();
            } catch (SettingsException se) {
                LogSystem.log(getClazz(), getClazz().getEnclosingMethod(), "Saving Settings", se);
            }
        }
        // Set the database xml file
        if (Settings.getDatabasesFile() == null ||
                Settings.getDatabasesFile().exists()) {
            Settings.setDatabasesFile("./settings/databases.xml");
            Settings.setDatabasesFileDefault("./settings/databases.xml");
            try {
                Settings.save();
            } catch (SettingsException se) {
                LogSystem.log(getClazz(), getClazz().getEnclosingMethod(), "Saving Settings", se);
            }
        }
        // Set DBXplora width
        if (Settings.getDBXploraWidth() == 0) {
            Settings.setDBXPloraWidth(200);
            Settings.setDBXPloraWidthDefault(200);
            try {
                Settings.save();
            } catch (SettingsException se) {
                LogSystem.log(getClazz(), getClazz().getEnclosingMethod(), "Saving Settings", se);
            }
        }
        // Set Look and Feel
        if (Settings.getLookAndFeel() == null ||
                Settings.getLookAndFeel().isEmpty()) {
            Settings.setLookAndFeel(javax.swing.UIManager.getSystemLookAndFeelClassName());
            Settings.setLookAndFeelDefault(javax.swing.UIManager.getSystemLookAndFeelClassName());
            try {
                Settings.save();
            } catch (SettingsException se) {
                LogSystem.log(getClazz(), getClazz().getEnclosingMethod(), "Saving Settings", se);
            }
        }
    }
    
    /**
     * 
     * @param parent 
     */
    public static void setApplicationBounds(Frame parent) {
        setApplicationBounds(parent.getBounds());
    }
    
    /**
     * 
     * @param bounds 
     */
    public static void setApplicationBounds(Rectangle bounds) {
        try {
            setValue("application-x", String.valueOf(bounds.x));
            setValue("application-y", String.valueOf(bounds.y));
            setValue("application-width", String.valueOf(bounds.width));
            setValue("application-height", String.valueOf(bounds.height));
        } catch (SettingsException se) {
            LogSystem.log(getClazz(), getClazz().getEnclosingMethod(), "Setting Bounds", se);
        }
    }
    
    /**
     * 
     * @param x
     * @param y
     * @param width
     * @param height 
     */
    public static void setApplicationBounds(int x, int y, int width, int height) {
        try {
            setValue("application-x", String.valueOf(x));
            setValue("application-y", String.valueOf(y));
            setValue("application-width", String.valueOf(width));
            setValue("application-height", String.valueOf(height));
        } catch (SettingsException se) {
            LogSystem.log(getClazz(), getClazz().getEnclosingMethod(), "Setting Bounds", se);
        }
    }
    
    /**
     * 
     * @param x
     * @param y 
     */
    public static void setApplicationLocation(int x, int y) {
        try {
            setValue("application-x", String.valueOf(x));
            setValue("application-y", String.valueOf(y));
        } catch (SettingsException se) {
            LogSystem.log(getClazz(), getClazz().getEnclosingMethod(), "Setting Location", se);
        }
    }
    
    /**
     * 
     * @param width
     * @param height 
     */
    public static void setApplicationSize(int width, int height) {
        try {
            setValue("application-x", String.valueOf(width));
            setValue("application-y", String.valueOf(height));
        } catch (SettingsException se) {
            LogSystem.log(getClazz(), getClazz().getEnclosingMethod(), "Setting Size", se);
        }
    }
    
    /**
     * 
     * @return 
     */
    public static Rectangle getApplicationBounds() {
        try {
            return new Rectangle(Integer.parseInt(getValue("application-x")),
                                        Integer.parseInt(getValue("application-y")),
                                            Integer.parseInt(getValue("application-width")),
                                                Integer.parseInt(getValue("application-height")));
        } catch (SettingsException | NumberFormatException e) {
            LogSystem.log(getClazz(), getClazz().getEnclosingMethod(), "Getting Bounds", e);
            return getApplicationBoundsDefault();
        }
    }
    
    /**
     * 
     * @param parent 
     */
    public static void setApplicationBoundsDefault(Frame parent) {
        setApplicationBoundsDefault(parent.getBounds());
    }
    
    /**
     * 
     * @param bounds 
     */
    public static void setApplicationBoundsDefault(Rectangle bounds) {
        try {
            setDefault("application-x", String.valueOf(bounds.x));
            setDefault("application-y", String.valueOf(bounds.y));
            setDefault("application-width", String.valueOf(bounds.width));
            setDefault("application-height", String.valueOf(bounds.height));
        } catch (SettingsException se) {
            LogSystem.log(getClazz(), getClazz().getEnclosingMethod(), "Setting Bounds Default", se);
        }
    }
    
    /**
     * 
     * @return 
     */
    public static Rectangle getApplicationBoundsDefault() {
        try {
            return new Rectangle(Integer.parseInt(getDefault("application-x")),
                                        Integer.parseInt(getDefault("application-y")),
                                            Integer.parseInt(getDefault("application-width")),
                                                Integer.parseInt(getDefault("application-height")));
        } catch (SettingsException | NumberFormatException e) {
            LogSystem.log(getClazz(), getClazz().getEnclosingMethod(), "Getting Bounds Default", e);
            return Constants.DEFAULT_BOUNDS;
        }
    }
    
    /**
     * 
     * @return 
     */
    public static String getApplicationName() {
        return Constants.APPLICATION_NAME;
    }
    
    /**
     * 
     * @return 
     */
    public static String getApplicationVersion() {
        return Constants.VERSION;
    }
    
    /**
     * 
     * @param databaseLibrarysDirectory 
     */
    public static void setDatabaseLibrarysDirectoryDefault(File databaseLibrarysDirectory) {
        setDatabaseLibrarysDirectoryDefault(databaseLibrarysDirectory.getPath());
    }
    
    /**
     * 
     * @param databaseLibrarysDirectory
     */
    public static void setDatabaseLibrarysDirectoryDefault(String databaseLibrarysDirectory) {
        try {
            setDefault("database-librarys-directory", databaseLibrarysDirectory);
        } catch (SettingsException se) {
            LogSystem.log(getClazz(), getClazz().getEnclosingMethod(), "Setting Database Library Directory Default", se);
        }
    }
    
    /**
     * 
     * @return 
     */
    public static File getDatabaseLibrarysDirectoryDefault() {
        try {
            return new File(getDefault("database-librarys-directory"));
        } catch (SettingsException se) {
            LogSystem.log(getClazz(), getClazz().getEnclosingMethod(), "Getting Database Library Directory Default", se);
            return null;
        }
    }
    
    /**
     * 
     * @param databaseLibrarysDirectory 
     */
    public static void setDatabaseLibrarysDirectory(File databaseLibrarysDirectory) {
        setDatabaseLibrarysDirectory(databaseLibrarysDirectory.getPath());
    }
    
    /**
     * 
     * @param databaseLibrarysDirectory 
     */
    public static void setDatabaseLibrarysDirectory(String databaseLibrarysDirectory) {
        try {
            setValue("database-librarys-directory", databaseLibrarysDirectory);
        } catch (SettingsException se) {
            LogSystem.log(getClazz(), getClazz().getEnclosingMethod(), "Setting Database Library Directory", se);
        }
    }
    
    /**
     * 
     * @return 
     */
    public static File getDatabaseLibrarysDirectory() {
        try {
            return new File(getValue("database-librarys-directory"));
        } catch (SettingsException se) {
            LogSystem.log(getClazz(), getClazz().getEnclosingMethod(), "Getting Database Library Directory", se);
        }
        return null;
    }
    
    /**
     * 
     * @param databases 
     */
    public static void setDatabasesFileDefault(String databases) {
        try {
            setDefault("databases", databases);
        } catch (SettingsException se) {
            LogSystem.log(getClazz(), getClazz().getEnclosingMethod(), "Setting Databases File", se);
        }
    }
    
    /**
     * 
     * @param databases 
     */
    public static void setDatabasesFileDefault(File databases) {
        setDatabasesFileDefault(databases.getPath());
    }
    
    /**
     * 
     * @return 
     */
    public static File getDatabasesFileDefault() {
        try {
            return new File(getDefault("databases"));
        } catch (SettingsException se) {
            LogSystem.log(getClazz(), getClazz().getEnclosingMethod(), "Getting Databases File", se);
        }
        return null;
    }
    
    /**
     * 
     * @param databases 
     */
    public static void setDatabasesFile(String databases) {
        try {
            setValue("databases", databases);
        } catch (SettingsException se) {
            LogSystem.log(getClazz(), getClazz().getEnclosingMethod(), "Setting Database File", se);
        }
    }
    
    /**
     * 
     * @param databases 
     */
    public static void setDatabasesFile(File databases) {
        setDatabasesFile(databases.getPath());
    }
    
    /**
     * 
     * @return 
     */
    public static File getDatabasesFile() {
        try {
            return new File(getValue("databases"));
        } catch (SettingsException se) {
            LogSystem.log(getClazz(), getClazz().getEnclosingMethod(), "Getting Databases File", se);
        }
        return null;
    }
    
    /**
     * 
     * @param logging 
     */
    public static void setLogging(boolean logging) {
        try {
            setValue("logging", Boolean.toString(logging));
        } catch (SettingsException se) {
            LogSystem.log(getClazz(), getClazz().getEnclosingMethod(), "Setting Logging", se);
        }
    }
    
    /**
     * 
     * @return 
     */
    public static boolean isLogging() {
        try {
            return Boolean.parseBoolean(getValue("logging"));
        } catch (SettingsException se) {
            LogSystem.log(getClazz(), getClazz().getEnclosingMethod(), "Getting Logging", se);
        }
        return false;
    }
    
    /**
     * 
     * @param logging 
     */
    public static void showStartupPage(boolean showStartupPage) {
        try {
            setValue("show-startup", Boolean.toString(showStartupPage));
        } catch (SettingsException se) {
            LogSystem.log(getClazz(), getClazz().getEnclosingMethod(), "Setting Show Startup Page", se);
        }
    }
    
    /**
     * 
     * @return 
     */
    public static boolean showStartupPage() {
        try {
            return Boolean.parseBoolean(getValue("show-startup"));
        } catch (SettingsException se) {
            LogSystem.log(getClazz(), getClazz().getEnclosingMethod(), "Getting Show Startup Page", se);
        }
        return true;
    }
    
    /**
     * 
     * @param width 
     */
    public static void setDBXPloraWidthDefault(int width) {
        try {
            setDefault("dbxplora-width", String.valueOf(width));
        } catch (SettingsException se) {
            LogSystem.log(getClazz(), getClazz().getEnclosingMethod(), "Setting DB XPlora Width Default", se);
        }
    }
    
    /**
     * 
     * @return 
     */
    public static int getDBXploraWidthDefault() {
        try {
            return Integer.parseInt(getDefault("dbxplora-width"));
        } catch (SettingsException | NumberFormatException e) {
            LogSystem.log(getClazz(), getClazz().getEnclosingMethod(), "Getting DB XPlora Width Default", e);
            return 200;
        }
    }
    
    /**
     * 
     * @param width 
     */
    public static void setDBXPloraWidth(int width) {
        try {
            setValue("dbxplora-width", String.valueOf(width));
        } catch (SettingsException se) {
            LogSystem.log(getClazz(), getClazz().getEnclosingMethod(), "Setting DB Xplora Width", se);
        }
    }
    
    /**
     * 
     * @return 
     */
    public static int getDBXploraWidth() {
        try {
            return Integer.parseInt(getValue("dbxplora-width"));
        } catch (SettingsException | NumberFormatException e) {
            LogSystem.log(getClazz(), getClazz().getEnclosingMethod(), "Getting DB Xplora Width", e);
            return getDBXploraWidthDefault();
        }
    }
    
    /**
     * 
     * @param laf 
     */
    public static void setLookAndFeelDefault(String laf) {
        try {
            setDefault("look-and-feel", laf);
        } catch (SettingsException se) {
            LogSystem.log(getClazz(), getClazz().getEnclosingMethod(), "Setting Look And Feel Default", se);
        }
    }
    
    /**
     * 
     * @return 
     */
    public static String getLookAndFeelDefault() {
        try {
            return getDefault("look-and-feel");
        } catch (SettingsException se) {
            LogSystem.log(getClazz(), getClazz().getEnclosingMethod(), "Getting Look And Feel Default", se);
            return javax.swing.UIManager.getSystemLookAndFeelClassName();
        }

    }
    
    /**
     * 
     * @param laf 
     */
    public static void setLookAndFeel(LookAndFeelInfo laf) {
        setLookAndFeel(laf.getClassName());
    }
    
    /**
     * 
     * @param laf 
     */
    public static void setLookAndFeel(String laf) {
        try {
            setValue("look-and-feel", laf);
        } catch (SettingsException se) {
            LogSystem.log(getClazz(), getClazz().getEnclosingMethod(), "Setting Look And Feel", se);
        }
    }
    
    /**
     * 
     * @return 
     */
    public static String getLookAndFeel() {
        try {
            return getValue("look-and-feel");
        } catch (SettingsException se) {
            LogSystem.log(getClazz(), getClazz().getEnclosingMethod(), "Getting Look And Feel", se);
            return getLookAndFeelDefault();
        }
    }
    
    /**
     * 
     * @param location 
     */
    public static void setSQLLocationDefault(File location) {
        try {
            setDefault("sql-location", location.getAbsolutePath());
        } catch (SettingsException se) {
            LogSystem.log(getClazz(), getClazz().getEnclosingMethod(), "Setting Look And Feel", se);
        }
    }
    
    /**
     * 
     * @return 
     */
    public static File getSQLLocationDefault() {
        try {
            return new File(getValue("sql-location"));
        } catch (SettingsException se) {
            LogSystem.log(getClazz(), getClazz().getEnclosingMethod(), "Getting Look And Feel Default", se);
            return new File(System.getProperty("./"));
        }
    }
    
    /**
     * 
     * @param location 
     */
    public static void setSQLLocation(File location) {
        try {
            setValue("sql-location", location.getAbsolutePath());
        } catch (SettingsException se) {
            LogSystem.log(getClazz(), getClazz().getEnclosingMethod(), "Setting Look And Feel", se);
        }
    }
    
    /**
     * 
     * @return 
     */
    public static File getSQLLocation() {
        try {
            return new File(getValue("sql-location"));
        } catch (SettingsException se) {
            LogSystem.log(getClazz(), getClazz().getEnclosingMethod(), "Getting Look And Feel", se);
            return getSQLLocationDefault();
        }
    }

}
